#include "Evaluation.h"

using namespace Nezha;

float FastEval::FastSin(float a)
{
	float re = (float)7.61e-03;
	float sqr = a * a;
	re *= sqr;
	re -= (float)1.6605e-01;
	re *= sqr;
	re += 1.0;
	re *= a;
	return re;
}

float FastEval::FastCos(float a)
{
	float re = (float)3.705e-02;
	float sqr = a * a;
	re *= sqr;
	re -= (float)4.967e-01;
	re *= sqr;
	re += 1.0;
	return re;
}

float FastEval::FastSinHP(float a)
{
	float re = (float)-2.39e-08;
	float sqr = a * a;
	re *= sqr;
	re += (float)2.7526e-06;
	re *= sqr;
	re -= (float)1.98409e-04;
	re *= sqr;
	re += (float)8.3333315e-03;
	re *= sqr;
	re -= (float)1.666666664e-01;
	re *= sqr;
	re += 1.0;
	re *= a;
	return re;
}

float FastEval::FastCosHP(float a)
{
	float re = (float)-2.605e-07;
	float sqr = a * a;
	re *= sqr;
	re += (float)2.47609e-05;
	re *= sqr;
	re -= (float)1.3888397e-03;
	re *= sqr;
	re += (float)4.16666418e-02;
	re *= sqr;
	re -= (float)4.999999963e-01;
	re *= sqr;
	re += 1.0;
	return re;
}

float FastEval::FastASin(float v)
{
	float sqrt_v = Sqrt(fabs(float(1.0-v)));
	float re = (float)-0.0187293;
	re *= v;
	re += (float)0.0742610;
	re *= v;
	re -= (float)0.2121144;
	re *= v;
	re += (float)1.5707288;
	re = NZ_PI_OVER2 - sqrt_v * re;
	return re;
}

float FastEval::FastASinHP(float v)
{
	float sqrt_v = Sqrt(fabs(float(1.0-v)));
	float re = (float)-0.0012624911;
	re *= v;
	re += (float)0.0066700901;
	re *= v;
	re -= (float)0.0170881256;
	re *= v;
	re += (float)0.0308918810;
	re *= v;
	re -= (float)0.0501743046;
	re *= v;
	re += (float)0.0889789874;
	re *= v;
	re -= (float)0.2145988016;
	re *= v;
	re += (float)1.5707963050;
	re = NZ_PI_OVER2 - sqrt_v*re;
	return re;
}

float FastEval::FastACos(float v)
{
	float sqrt_v = Sqrt(fabs(float(1.0-v)));
	float re = (float)-0.0187293;
	re *= v;
	re += (float)0.0742610;
	re *= v;
	re -= (float)0.2121144;
	re *= v;
	re += (float)1.5707288;
	re *= sqrt_v;
	return re;
}

float FastEval::FastACosHP(float v)
{
	float sqrt_v = Sqrt(fabs(float(1.0-v)));
	float re = (float)-0.0012624911;
	re *= v;
	re += (float)0.0066700901;
	re *= v;
	re -= (float)0.0170881256;
	re *= v;
	re += (float)0.0308918810;
	re *= v;
	re -= (float)0.0501743046;
	re *= v;
	re += (float)0.0889789874;
	re *= v;
	re -= (float)0.2145988016;
	re *= v;
	re += (float)1.5707963050;
	re *= sqrt_v;
	return re;
}

float FastEval::FastTan(float a)
{
	float re = (float)2.033e-01;
	float sqr = a * a;
	re *= sqr;
	re += (float)3.1755e-01;
	re *= sqr;
	re += 1.0;
	re *= a;
	return re;
}

float FastEval::FastTanHP(float a)
{
	float re = (float)9.5168091e-03;
	float sqr = a * a;
	re *= sqr;
	re += (float)2.900525e-03;
	re *= sqr;
	re += (float)2.45650893e-02;
	re *= sqr;
	re += (float)5.33740603e-02;
	re *= sqr;
	re += (float)1.333923995e-01;
	re *= sqr;
	re += (float)3.333314036e-01;
	re *= sqr;
	re += 1.0;
	re *= a;
	return re;
}

float FastEval::FastATan(float v)
{
	float re = (float)0.0208351;
	float sqr = v * v;
	re *= sqr;
	re -= (float)0.085133;
	re *= sqr;
	re += (float)0.180141;
	re *= sqr;
	re -= (float)0.3302995;
	re *= sqr;
	re += (float)0.999866;
	re *= v;
	return re;
}

float FastEval::FastATanHP(float v)
{
	float re = (float)0.0028662257;
	float sqr = v * v;
	re *= sqr;
	re -= (float)0.0161657367;
	re *= sqr;
	re += (float)0.0429096138;
	re *= sqr;
	re -= (float)0.0752896400;
	re *= sqr;
	re += (float)0.1065626393;
	re *= sqr;
	re -= (float)0.1420889944;
	re *= sqr;
	re += (float)0.1999355085;
	re *= sqr;
	re -= (float)0.3333314528;
	re *= sqr;
	re += 1.0;
	re *= v;
	return re;
}

float FastEval::FastInvSqrt(float v)
{
	// newton method, the first iteration value comes from QUAKE3.
	float half = 0.5f * v;
	int i  = *(int*)&v;
	i = 0x5f3759df - (i >> 1);
	v = *(float*)&i;
	v = v * (1.5f - half * v * v);
	return v;
}